import 'dart:async';
import 'package:flutter/material.dart';
import 'package:yurun_smartmerchants/generated/json/base/json_convert_content.dart';
import 'package:yurun_smartmerchants/models/verify_code_entity.dart';
import 'package:yurun_smartmerchants/net/ApiInterface.dart';
import 'package:yurun_smartmerchants/net/NetUtil.dart';
import 'package:yurun_smartmerchants/res/colours.dart';
import 'package:oktoast/oktoast.dart';

/// 可用时使用的字体样式。
final TextStyle _availableStyle = TextStyle(
  fontSize: 16.0,
  color: Colours.app_main,
);

/// 不可用时使用的样式。
final TextStyle _unavailableStyle = TextStyle(
  fontSize: 16.0,
  color: Colours.text_gray,
);

// ignore: must_be_immutable
class ResetCodePage extends StatefulWidget {
  /// 倒计时的秒数，默认60秒。
  final int countdown;

  /// 用户点击时的回调函数。
  final Function onTapCallback;

  /// 是否可以获取验证码，默认为`false`。
  final bool available;
  ///电话号码
  String phoneNum;
  ///可用时使用的字体样式
  final TextStyle availableFontStyle;
  ///不可用时使用的字体样式
  final TextStyle unavailableFontStyle;

  ResetCodePage({
    this.countdown: 60,
    this.onTapCallback,
    this.available: true,
    @required this.phoneNum,
    this.availableFontStyle,
    this.unavailableFontStyle,
  });

  @override
  _ResetCodePageState createState() => _ResetCodePageState();
}

class _ResetCodePageState extends State<ResetCodePage> {
  /// 倒计时的计时器。
  Timer _timer;

  /// 当前倒计时的秒数。
  int _seconds;

  /// 当前墨水瓶（`InkWell`）的字体样式。
  TextStyle inkWellStyle;

  /// 当前墨水瓶（`InkWell`）的文本。
  String _verifyStr = '获取验证码';
  bool isCheck = false;

  @override
  void initState() {
    super.initState();
    _seconds = widget.countdown;
    inkWellStyle = widget.availableFontStyle == null ? _availableStyle : widget.availableFontStyle;
  }

  /// 启动倒计时的计时器。
  void _startTimer() {
    // 计时器（`Timer`）组件的定期（`periodic`）构造函数，创建一个新的重复计时器。
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      if (_seconds == 0) {
        _cancelTimer();
        _seconds = widget.countdown;
        setState(() {});
        return;
      }
      _seconds--;
      _verifyStr = '已发送$_seconds' + 's';
      inkWellStyle = widget.unavailableFontStyle == null ? _unavailableStyle : widget.unavailableFontStyle;
      if (mounted) {
        setState(() {});
        if (_seconds == 0) {
          isCheck = false;
          _verifyStr = '重新发送';
          inkWellStyle = widget.availableFontStyle == null ? _availableStyle : widget.availableFontStyle;
        }
      }
    });
  }

  /// 取消倒计时的计时器。
  void _cancelTimer() {
    /// 计时器（`Timer`）组件的取消（`cancel`）方法，取消计时器。
    _timer?.cancel();
  }

  @override
  Widget build(BuildContext context) {
    ///墨水瓶（`InkWell`）组件，响应触摸的矩形区域。
    return widget.available
        ? InkWell(
            child: Text(
              '$_verifyStr',
              style: inkWellStyle,
            ),
            onTap: () {
              if (widget.phoneNum == null || widget.phoneNum.isEmpty) {
                showToast('请输入手机号码~');
                return;
              }
              if (!isPhone(widget.phoneNum)) {
                showToast('手机号码格式不正确~');
                return;
              }
              if (_seconds == widget.countdown && !isCheck) {
                isCheck = true;
                _startTimer();
                _sendVerifyCode(widget.phoneNum);
              }
            })
        : InkWell(
            child: Text(
              '获取验证码',
              style: widget.unavailableFontStyle == null ? _unavailableStyle : widget.unavailableFontStyle,
            ),
          );
  }

  bool isPhone(String mobile) {
    RegExp exp = RegExp(
        r'^((13[0-9])|(14[0-9])|(15[0-9])|(16[0-9])|(17[0-9])|(18[0-9])|(19[0-9]))\d{8}$');
    bool matched = exp.hasMatch(mobile);
    return matched;
  }

  void _sendVerifyCode(String phoneNum) {
    ApiInterface.getVerifyCode(phoneNum).then((data) {
      VerifyCodeEntity verifyCodeEntity =
          JsonConvert.fromJsonAsT<VerifyCodeEntity>(data);
      if (verifyCodeEntity.success) {
        showToast('验证码已发送，请注意查收');
      }
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _cancelTimer();
  }
}
